import Base from './Base.js';
import { GRAPH_TYPES } from './Graph.enum.js';
import Color from '../Color.js';
// import Point from '../Point.js';

class Rect extends Base {
    constructor({ pos } = {}) {
        super(...arguments);
        this.name = GRAPH_TYPES.RECT;
        if (!this.points || !this.points.length) this.points = [pos, pos, pos, pos];
        // 兼容之前数据，处理points为[左上,右上,右下，左下]
        // else this.points = this._recaculatePoints(this.points, true);
        this.update(0, this.points[0]);
    }

    initUpdate(start, end) {
        this.points = this._recaculatePoints([start, end]);
        // console.error('Rect.initUpdate:', this.points);
        this.x = Math.round((start.x + end.x) / 2);
        this.y = Math.round((start.y + end.y) / 2);
        // console.log('[Rect] initUpdate: ', start, end, JSON.stringify(this.points));
    }

    _recaculatePoints(points, reverse = false) {
        if (!points || !points.length) return points;
        let x1 = points[0].x,
            y1 = points[0].y,
            x2 = points[0].x,
            y2 = points[0].y;
        points.forEach(p => {
            x1 = Math.min(p.x, x1);
            y1 = reverse ? Math.min(p.y, y1) : Math.max(p.y, y1);
            x2 = Math.max(p.x, x2);
            y2 = reverse ? Math.max(p.y, y2) : Math.min(p.y, y2);
        });
        return [
            { x: x1, y: y1 },
            { x: x2, y: y1 },
            { x: x2, y: y2 },
            { x: x1, y: y2 }
        ]; //eslint-disable-line
    }

    createPath() {
        let r = (1 / this.scaling) * 5 * this.ratio;
        this.ctx.beginPath();
        this.ctx.arc(this.x, this.y, r, 0, Math.PI * 2, false);
    }

    /**
     * @param i: number: point index, Infinity: in path
     */
    update(i, pos) {
        // console.log('[Rect] update: ', i, pos, JSON.stringify(this.points));
        if (i === Infinity) {
            let that = this,
                x1 = pos.x - this.x,
                y1 = pos.y - this.y;
            // x1 = (pos.x - this.x) * this.ratio,
            // y1 = (pos.y - this.y) * this.ratio;
            this.points.forEach((p, i) => {
                that.points[i] = { x: p.x + x1, y: p.y + y1 };
            });
            // this.points = this._recaculatePoints(this.points);
            this.x = Math.round(pos.x);
            this.y = Math.round(pos.y);
        } else {
            // this.points[i] = pos;
            // let x = 0,
            //     y = 0;
            // this.points.forEach(p => {
            //     x += p.x;
            //     y += p.y;
            // });
            // this.x = Math.round(x / this.points.length);
            // this.y = Math.round(y / this.points.length);
            if (i === 0) {
                // this.points[3].x = pos.x;
                // this.points[1].y = pos.y;
                // 限制反向拉伸
                if (pos.x < this.points[2].x && pos.y > this.points[2].y) this.initUpdate(this.points[2], pos);
                // 处理原始绘制了一条直线后继续拖动点的逻辑。。 有瑕疵 --guxulei
                // if (Point.equals(this.points[0], this.points[3])) {
                //     this.initUpdate(this.points[2], pos);
                //     // this.points[i] = pos;
                //     // this.points[3].x = pos.x;
                //     // this.points[1].y = pos.y;
                //     // this.initControlPoints();
                // }
            } else if (i === 1) {
                // this.points[2].x = pos.x;
                // this.points[0].y = pos.y;
                // 限制反向拉伸
                if (pos.x > this.points[3].x && pos.y > this.points[3].y) this.initUpdate(this.points[3], pos);
                // 处理原始绘制了一条直线后继续拖动点的逻辑。。 有瑕疵 --guxulei
                // if (Point.equals(this.points[0], this.points[3])) {
                //     this.initUpdate(this.points[3], pos);
                //     // this.points[i] = pos;
                //     // this.points[2].x = pos.x;
                //     // this.points[0].y = pos.y;
                //     // this.initControlPoints();
                // }
            } else if (i === 2) {
                // this.points[1].x = pos.x;
                // this.points[3].y = pos.y;
                // 限制反向拉伸
                if (pos.x > this.points[0].x && pos.y < this.points[0].y) this.initUpdate(this.points[0], pos);
                // 处理原始绘制了一条直线后继续拖动点的逻辑。。 有瑕疵 --guxulei
                // if (Point.equals(this.points[0], this.points[3])) {
                //     this.initUpdate(this.points[0], pos);
                //     // this.points[i] = pos;
                //     // this.points[1].x = pos.x;
                //     // this.points[3].y = pos.y;
                //     // this.initControlPoints();
                // }
            } else if (i === 3) {
                // this.points[0].x = pos.x;
                // this.points[2].y = pos.y;
                // 限制反向拉伸
                if (pos.x < this.points[1].x && pos.y < this.points[1].y) this.initUpdate(this.points[1], pos);
                // 处理原始绘制了一条直线后继续拖动点的逻辑。。 有瑕疵 --guxulei
                // if (Point.equals(this.points[0], this.points[3])) {
                //     this.initUpdate(this.points[1], pos);
                //     // this.points[i] = pos;
                //     // this.points[0].x = pos.x;
                //     // this.points[2].y = pos.y;
                //     // this.initControlPoints();
                // }
            }
        }
    }

    // createPath() {
    //     this.ctx.beginPath();
    //     this.ctx.arc(this.x, this.y, 5, 0, Math.PI * 2, false);
    // }
    drawPath(ctx) {
        ctx.beginPath();

        let r = Math.round(this.radius);

        // let p = this.points,
        //     yr = this.isReverse ? -1 : 1;
        // ctx.moveTo(p[0].x, p[0].y * yr);
        // ctx.lineTo(p[1].x, p[1].y * yr);
        // ctx.lineTo(p[2].x, p[2].y * yr);
        // ctx.lineTo(p[3].x, p[3].y * yr);
        // ctx.lineTo(p[0].x, p[0].y * yr);

        // if (this.lineWidth && this.lineWidth > 2 * r) r = Math.round(this.lineWidth / 2);
        this.points.forEach((p, i) => {
            let y = this.isReverse ? -p.y : p.y;
            if (i === 0) {
                ctx.arc(p.x + r, y + r, r, Math.PI, (Math.PI * 3) / 2);
            } else if (i === 1) {
                ctx.lineTo(p.x - r, y);
                ctx.arc(p.x - r, y + r, r, (Math.PI * 3) / 2, Math.PI * 2);
            } else if (i === 2) {
                ctx.lineTo(p.x, y - r);
                ctx.arc(p.x - r, y - r, r, 0, (Math.PI * 1) / 2);
            } else if (i === 3) {
                ctx.lineTo(p.x + r, y);
                ctx.arc(p.x + r, y - r, r, (Math.PI * 1) / 2, Math.PI);
                ctx.lineTo(this.points[0].x, (this.isReverse ? -this.points[0].y : this.points[0].y) + r);
            }
        });

        // let p = this.points,
        //     yr = this.isReverse ? -1 : 1;
        // ctx.moveTo(p[0].x + r, p[0].y * yr);

        // ctx.moveTo(p[0].x + r, p[0].y * yr);

        // ctx.arcTo(p[1].x, p[0].y * yr, p[1].x, p[2].y * yr, r);
        // ctx.arcTo(p[1].x, p[2].y * yr, p[0].x, p[2].y * yr, r);
        // ctx.arcTo(p[0].x, p[2].y * yr, p[0].x, p[0].y * yr, r);
        // ctx.arcTo(p[0].x, p[0].y * yr, p[1].x, p[0].y * yr, r);

        // ctx.arcTo(p[0].x, p[0].y * yr, p[0].x - r, p[0].y * yr, r);

        // ctx.lineTo(p[1].x - r, p[1].y * yr);
        // ctx.arcTo(p[1].x, p[1].y * yr, p[1].x, p[1].y * yr - r, r);
        //
        // ctx.lineTo(p[2].x, p[2].y * yr + r);
        // ctx.arcTo(p[2].x, p[2].y * yr, p[2].x - r, p[2].y * yr, r);
        //
        // ctx.lineTo(p[3].x + r, p[3].y * yr);
        // ctx.arcTo(p[3].x, p[3].y * yr, p[3].x, p[3].y * yr + r, r);
        //
        // ctx.lineTo(p[0].x, p[0].y * yr - r);
        // ctx.arcTo(p[0].x, p[0].y * yr, p[0].x + r, p[0].y * yr, r);

        // ctx.lineTo(p[1].x + r, p[1].y * yr);
        // ctx.arcTo(p[1].x, p[1].y * yr, p[1].x, p[1].y * yr + r, r);

        // ctx.closePath();
    }

    // 绘制两点之间线长度（同卷尺功能）
    drawLineLength(scaling) {
        this.ctx.save();

        let textSize = this.lineWidth;
        if (scaling) {
            textSize = (1 / scaling) * 20;
        }
        // console.log('Rect.drawLineLength: ', ctx);
        // 第一条（上边） 边长
        let lineLength = this.getLineLength(this.points[0], this.points[1]),
            middlePoint = this.getLineMiddlePoint(this.points[0], this.points[1]);
        // textFontSize = textSize * 10;
        this.ctx.font = textSize + 'px Arial';
        this.ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';
        this.ctx.textAlign = 'center';
        this.ctx.textBaseline = 'bottom';
        this.ctx.fillText(lineLength, middlePoint.x, -middlePoint.y - 50);

        // 第四条（左边） 边长
        lineLength = this.getLineLength(this.points[3], this.points[0]);
        middlePoint = this.getLineMiddlePoint(this.points[3], this.points[0]);
        this.ctx.fillText(lineLength, middlePoint.x + 50, -middlePoint.y);

        this.ctx.stroke();
        this.ctx.restore();
    }

    drawSelected(ctx) {
        if (ctx) this.ctx = ctx;
        // let ps = this._recaculatePoints(this.points);
        let ps = this.points;
        if (ps[0].x !== this.points[0].x) this.points = ps;
        // let r = Math.round(this.radius); //eslint-disable-line
        this.ctx.save();
        this.ctx.lineWidth = this.lineWidth;
        this.ctx.strokeStyle = this.strokeStyle;
        this.drawPath(this.ctx);
        this.ctx.stroke();
        this.ctx.restore();
    }

    draw(ctx, drawDashLine = false) {
        if (ctx) this.ctx = ctx;
        // this.points = this._recaculatePoints(this.points);
        // let ps = this._recaculatePoints(this.points);
        let ps = this.points;
        if (ps[0].x !== this.points[0].x) this.points = ps;
        // let r = Math.round(this.radius); //eslint-disable-line
        // let penSize = (1 / this.scaling) * 2 * this.ratio;

        // console.log('[Rect] draw: ', r, JSON.stringify(this.points));
        this.ctx.save();
        // this.ctx.lineWidth = penSize;
        this.drawPath(this.ctx);
        if (this.fillStyle) {
            this.ctx.fillStyle = this.fillStyle;
            this.ctx.fill();
        }
        if (drawDashLine) {
            let penSize = 1 / this.scaling || 100;
            this.ctx.lineWidth = penSize * 10;
            this.ctx.strokeStyle = Color.lightenDarkenColor(this.fillStyle, 0.3);
            this.ctx.setLineDash([penSize * 20, penSize * 20]);
            this.ctx.lineCap = 'round';
        } else {
            this.ctx.lineWidth = this.lineWidth;
            this.ctx.strokeStyle = this.strokeStyle;
        }
        this.ctx.stroke();
        this.ctx.restore();

        //绘制平移/更新图形锚点基准点
        // this.drawAnchorPoint();
        //绘制未连接点 - 未避免车辆绘制，修改到Painter中调用
        // this.drawUnConnectPoints();
    }

    drawCached(ctx) {
        ctx.save();
        // this.drawPath(ctx);
        let penSize = 1 / this.scaling || 100;
        // ctx.fillStyle = Color.lightenDarkenColor(this.fillStyle, 0.3);
        // ctx.fill();
        ctx.lineWidth = penSize * 5;
        ctx.strokeStyle = 'rgba(0, 0, 255, 0.6)';
        ctx.setLineDash([penSize * 10, penSize * 10]);
        ctx.lineCap = 'round';
        ctx.stroke();
        ctx.restore();
    }

    _getPathDescription(points) {
        // let yr = this.isReverse ? -1 : 1;
        // let ps = this._recaculatePoints(points, true);
        let ps = points;
        let p = { x: ps[3].x, y: ps[3].y }, // caculate the start point
            w = Math.abs(ps[1].x - ps[0].x),
            h = Math.abs(ps[3].y - ps[0].y);
        // points.forEach(v => {
        //     if (v.x < p.x && v.y < p.y) p = v;
        // });
        // console.log('[Rect] _getPathDescription: ', p, w, h, JSON.stringify(ps));
        let d = '';
        d += 'x="' + p.x + '" ';
        d += 'y="' + p.y + '" ';
        d += 'width="' + w + '" ';
        d += 'height="' + h + '" ';
        return d;
    }

    getSVGCodes() {
        // <polygon stroke-width="603.6810736797684" fill="rgba(30,30,30,0.30)" points="102500,113000 102500,69000 107500,69000 107500,113000 " stroke="none"></polygon>
        // let codes = '<polygon stroke-linecap="round" ';
        // codes += 'stroke="' + this.strokeStyle + '" ';
        // codes += 'stroke-width="' + this.lineWidth + '" ';
        // codes += 'fill="' + (this.fillStyle ? this.fillStyle : 'none') + '" ';
        // codes += 'points="' + this._getPathDescription(this.points) + '" ';
        // codes += '></polygon>';
        // return codes;

        // <rect stroke="rgba(0,0,80,0.89)" fill="rgba(238,42,60,0.94)" stroke-width="200" x="-3500" y="-1500" width="6000" height="3000" rx="300"></rect>
        let codes = '<rect stroke-linecap="round" ';
        codes += 'stroke="' + this.strokeStyle + '" ';
        codes += 'stroke-width="' + this.lineWidth + '" ';
        codes += 'fill="' + (this.fillStyle ? this.fillStyle : 'none') + '" ';
        codes += this._getPathDescription(this.points) + ' ';
        codes += this.radius ? 'rx="' + this.radius + '" ' : '';
        codes += '></rect>';
        return codes;
    }
}

export default Rect;
